package sprites;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;

public abstract class Sprite {
	
	private Point	pos = new Point(0,0);
	private Point	oldPos = new Point(0,0);
	
	private Color	color = defaultColor;
	private Image	texture = null;
	private boolean	selected = false;
	
	private boolean drawEdge = false;
	
	private String	name = "";
	
	private static final Point	NAME_OFFSET = new Point(0,-5);
	public static Color defaultColor;
	
	public abstract boolean	containsPoint(Point P);						// Determines if this sprite covers the given point
	
	public static final ArrayList<Sprite>	all = new ArrayList<Sprite>();

	public Sprite(Point P) {
		setPos(P);
		setColor(defaultColor);
		all.add(this);
	}
	
	public Point getPos() {
		return pos;
	}

	public void setPos(Point pos) {
		this.pos = pos;
	}

	public Color getColor() {
		if (this.color != null) {
			if (!isSelected()) {
				return this.color;
			} else {
				return new Color(
					this.color.getRed(),
					this.color.getBlue(),
					this.color.getGreen(),
					this.color.getAlpha()/2
				);
			}
		} else {
			return Sprite.defaultColor;
		}
	}

	public void setColor(Color color) {
		this.color = color;
	}
	
	public void paintPoint(Graphics G, Rectangle R) {
		// Assuming that the rectangle R represents the pixel for 
		// the position of the sprite
		// The default operation will just draw the pixel location
		Color	oldColor = G.getColor();
		G.setColor(this.getColor());
		G.fill3DRect(R.x, R.y, R.width, R.height, true);
		
		G.setColor(Color.black);
		G.setXORMode(Color.black);
		drawEdges(G,R);
		
		G.setPaintMode();
		
		G.setColor(oldColor);
		
		
	}

	public boolean isSelected() {
		return selected;
	}

	public void setSelected(boolean selected) {
		this.selected = selected;
	}

	public Point getOldPos() {
		return oldPos;
	}
	public void setOldPos(Point oldPos) {
		this.oldPos = oldPos;
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public abstract String toXml();
	public abstract void fromXml(String xml);
	
	public static Sprite fromXmlGenerate(String xml) {
		// TODO: Determine the type of xml and go from there
		return null;
	}

	public boolean isDrawEdge() {
		return drawEdge;
	}

	public void setDrawEdge(boolean drawEdge) {
		this.drawEdge = drawEdge;
	}


	//
	// Internal Methods
	//
	protected void drawEdges(Graphics G, Rectangle R) {
		drawAllEdge(G,R);
	}
	protected void drawNorthEdge(Graphics G, Rectangle R) {
		Color oldColor = G.getColor();
		G.setColor(Color.black);
		G.drawLine(R.x, R.y, R.x+R.width, R.y);
		G.setColor(oldColor);
	}
	protected void drawSouthEdge(Graphics G, Rectangle R) {
		Color oldColor = G.getColor();
		G.setColor(Color.black);
		G.drawLine(R.x, R.y+R.height, R.x+R.width, R.y+R.height);		
		G.setColor(oldColor);
	}
	protected void drawEastEdge(Graphics G, Rectangle R) {	
		Color oldColor = G.getColor();
		G.setColor(Color.black);
		G.drawLine(R.x+R.width, R.y, R.x+R.width, R.y+R.height);		
		G.setColor(oldColor);
	}
	protected void drawWestEdge(Graphics G, Rectangle R) {	
		Color oldColor = G.getColor();
		G.setColor(Color.black);
		G.drawLine(R.x, R.y, R.x, R.y+R.height);		
		G.setColor(oldColor);
	}
	protected void drawAllEdge(Graphics G, Rectangle R) {
		drawNorthEdge(G,R);
		drawSouthEdge(G,R);
		drawEastEdge(G,R);
		drawWestEdge(G,R);
	}
	protected void drawLine(Graphics G, Point P1, Point P2) {
		Color	oldColor = G.getColor();
		G.setColor(Color.black);
		G.drawLine(P1.x, P1.y, P2.x, P2.y);
		G.setColor(oldColor);
	}
	protected void drawName(Graphics G, Point P, Color C) {
		Color	oldColor = G.getColor();
		G.setColor(C);
		if (name!=null) {
			G.drawString(this.name, P.x + NAME_OFFSET.x, P.y + NAME_OFFSET.y );
		}
		G.setColor(oldColor);
	}

	public Image getTexture() {
		return texture;
	}

	public void setTexture(Image texture) {
		this.texture = texture;
	}
}
